<?php
namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
use think\Paginator;
use think\Validate;
require_once(dirname(__FILE__) . '/../../../vendor/jose/JWT.php');
require_once(dirname(__FILE__) . '/../../../vendor/jose/JWS.php');
require_once(dirname(__FILE__) . '/../../../vendor/jose/URLSafeBase64.php');
require_once(dirname(__FILE__) . '/../../../vendor/jose/Exception.php');
require_once(dirname(__FILE__) . '/../../../vendor/jose/Exception/InvalidFormat.php');
require_once(dirname(__FILE__) . '/../../../vendor/jose/Exception/VerificationFailed.php');


/**
 * 活动接口
 */
class Activity extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['*'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    //const DNS = 'http://mainnet.bibo.camwallet.cn:8081/';
    const DNS = 'http://testnet.bibo.camwallet.cn:8081/';

    /**
     * 活动是否结束
     */
    public function isOver($activityId)
    {
        $time = time();
        $endTime = Db::name('activity')->where('activity_id',$activityId)->value('endtime');
        if ( $endTime < $time ) {
            return 0;
        }
        return 1;
    }

    /**
     * 判断是否参加过活动
     */
    public function isActivity($activityId, $userId, $deviceToken, $address) {
        //设备是否参与过，1:已领取过，0:未领取过
        if ( !empty($deviceToken) ) {
            if ( !empty($address) ) {
                //设备是否领取过
                $deviceList = Db::name('receive')->where('activity_id',$activityId)->where('device_token',$deviceToken)->find();
                if ( !empty($deviceList) ) {
                    return 1;
                }else {
                    //账号是否领取过
                    $accountList = Db::name('receive')->where('activity_id',$activityId)->where('user_id',$userId)->find();
                    if ( !empty($accountList) ) {
                        return 1;
                    }else {
                        return 0;
                    }
                }
            }else {
                //设备是否领取过
                $deviceList = Db::name('receive')->where('activity_id',$activityId)->where('device_token',$deviceToken)->find();
                if ( !empty($deviceList) ) {
                    return 1;
                }else {
                    //账号是否领取过
                    $accountList = Db::name('receive')->where('activity_id',$activityId)->where('user_id',$userId)->find();
                    if ( !empty($accountList) ) {
                        return 0;
                    }
                }
            }
        }

        return 0;
    }

    /**
     * 是否添加用户数据
     */
    public function getUserReceive() {
        $param = $this->request->post();
        $jsonData = $this->joseDecode($param['msg']);
        $activityId = $jsonData['activity_id'];
        $userId = $jsonData['user_id'];
        $mobile = $jsonData['mobile'];
        $email = $jsonData['email'];
        $deviceType = $jsonData['device_type'];
        $deviceToken = $jsonData['device_token'];
        $deviceId = $jsonData['device_id'];
        if ( empty($deviceToken) && empty($deviceId) ) {
            $this->error('非法请求！');
        }
        //获取相关数据
        $rankList = $this->rank($activityId);
        $myReceive = $this->myReceiveInfo($activityId,$userId);
        //根据活动Id和userId判断该用户是否存在
        $currentInfo = Db::name('receive')->where('activity_id',$activityId)->where('user_id',$userId)->find();
        if ( !empty($currentInfo) ) {
            //是否可以参加活动
            $result = $this->isActivity($activityId, $userId, $deviceToken,$currentInfo['address']);
            if ( !empty($myReceive) && empty($currentInfo['address']) ) {
                $myReceive['type'] = 1;
            }
            //$num = $this->getMyCam($activityId, $userId, $mobile, $email, $deviceToken);
            if ( $result == 1 ) {
                $groupData = array(
                    'status' => 1,
                    'rankList' => $rankList,
                    'myReceive' => $myReceive
                );
                $this->success('该设备已领取过！',$groupData);
            }else {
               $groupData = array(
                    'status' => 0,
                    'rankList' => $rankList,
                    'myReceive' => $myReceive
                );
               $this->success('您还未领取奖品',$groupData);
            }
        }else {
            //使用同一个设备，但是是不同的账号
            $userInfo = Db::name('receive')->where('activity_id',$activityId)->where('device_token',$deviceToken)->find();
            if ( !empty($userInfo) ) {
                $myReceive['type'] = 1;
                $groupData = array(
                    'status' => 1,
                    'rankList' => $rankList,
                    'myReceive' => $myReceive
                );
                $this->success('该设备已经领取过!',$groupData);
            }else {
                $invitationCode = $this->makeInviteCode();
                $myReceive['invitation_code'] = $invitationCode;
                $data = array(
                    'activity_id' => $activityId,
                    'user_id' => $userId,
                    'mobile'  => $mobile,
                    'email'   => $email,
                    'invitation_code' => $invitationCode,
                    'device_type' => $deviceType
                );
                $result = Db::name('receive')->data($data)->insert();
                if ( $result === false ) {
                    $this->error('获取用户参加活动信息失败',$result);
                }else {
                    $groupData = array(
                        'status' => 0,
                        'rankList' => $rankList,
                        'myReceive' => $myReceive
                    );
                    $this->success('获取用户参加活动信息成功',$groupData);
                }
            }
        }
    }

    /**
     * 抽奖
     */
    public function getLottery()
    {
        $total = 1000000;
        if ( $this->request->isPost() ) {
            $msgData = $this->request->post('msgData');
            $jsonData = $this->joseDecode($msgData);
            $activityId = $jsonData['activity_id'];
            $userId = $jsonData['user_id'];
            $deviceToken = $jsonData['device_token'];
            $deviceId = $jsonData['device_id'];
            $invitationCode = $this->request->post('invitation_code');
            $address = $this->request->post('address');
            if ( empty($deviceToken) ) {
                $this->error('非法请求！');
            }
            if ( empty($deviceToken) && empty($deviceId) ) {
                $this->error('非法请求！');
            }
            $rule = [
                'address'  => 'require',
                'invitation_code'  => 'require|max:6'
            ];
            $msg = [
                'address.require' => '地址不能为空',
                'invitation_code.require'  => '邀请码不能为空',
                'invitation_code.max'  => '邀请码不能大于6位'
            ];
            $data = [
                'address'  => $address,
                'invitation_code'  => $invitationCode
            ];
            $validate = new Validate($rule, $msg);
            $result = $validate->check($data);
            if ( !$result ) {
                $this->error(__($validate->getError()), null);
                return false;
            }
        }
        //判断是否还有机会抽奖
        $quantity = Db::name('receive')->where('activity_id',$activityId)->sum('quantity');
        $inviteQuantity = Db::name('receive')->where('activity_id',$activityId)->sum('invite_quantity');
        $sum = $quantity + $inviteQuantity;
        $remain = $total - $sum;
        if ( $remain <= 5 ) {
            $this->error('很遗憾CAM已被领光,下次早点过来哦！');
        }
        $param = array(
            'wallet_type_name' => 'cam',
            'address' => $address
        );
        $where = array(
            'activity_id' =>$activityId,
            'address' => $address
        );
        //判断地址是否是CAM
        $url =  self::DNS . 'user/public/checkedAddress';
        $curlData = sendCurl($url,$param,'POST');
        if ( $curlData['data']['result'] != 1 ) {
            $this->error('您输入的地址不是CAM地址,请检查后重新输入!',[]);
        }
        //判断地址是否领取过CAM
        $info = Db::name('receive')->where($where)->find();
        if ( !empty($info) ) {
            $this->error('该钱包已领取过！',$info);
        }
        //判读邀请码是否有效
        $ownCode = Db::name('receive')->where('activity_id',$activityId)->where('user_id',$userId)->value('invitation_code');
        if ( $ownCode == strtolower($invitationCode)) {
            $this->error('用户本人邀请码无效',$ownCode);
        }
        //获取CAM数量
        $regNum = $this->getCamRandom();
        //判断该用户输入的邀请码是系统默认的还是别人分享的邀请码
        $invitationInfo = Db::name('receive')->where('activity_id',$activityId)->where('invitation_code',$invitationCode)->find();
        if ( empty($invitationInfo) ) {
            $this->error('您输入的邀请码无效',$invitationInfo);
        }
        $invitationId = $invitationInfo['user_id'];
        // 启动事务
        Db::startTrans();
        try {
            //更新自己的信息(和邀请人获得的CAM)
            $shareNum = $this->getCamRandom();
            Db::name('receive')->where('activity_id',$activityId)->where('user_id',$userId)
                ->update([
                    'address' => $address,
                    'recommended_id' => $invitationId,
                    'recommended_amount' => $shareNum,
                    'quantity' => $regNum,
                    'device_token' => $deviceToken,
                    'receivetime' => time(),
                    'updatetime' => time()
                ]);
            $inviteInfo = Db::name('receive')->where('activity_id',$activityId)->where('user_id',$invitationId)->find();
            if ( empty($invitationId) ) {
                Db::name('receive')->where('activity_id',$activityId)->where('user_id',$invitationId)->update([
                    'recommend_num' => Db::raw('recommend_num+1'),
                    'invite_quantity' =>  $inviteInfo['invite_quantity'] + $shareNum,
                    'updatetime' => time(),
                ]);
            }else {
                Db::name('receive')->where('activity_id',$activityId)->where('user_id',$invitationId)->update([
                    'recommend_num' => Db::raw('recommend_num+1'),
                    'invite_quantity'	=> $inviteInfo['invite_quantity'] + $shareNum,
                    'updatetime' => time()
                ]);
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
        }

        $this->success('领取CAM成功',$regNum);
    }

    /**
     * 邀请好友排名前十的数据
     */
    public function rank($activityId)
    {
        $topTenList = Db::query( "SELECT  id,mobile,email, `quantity`+`invite_quantity` as amount FROM `bi_receive` WHERE `activity_id` = '$activityId' ORDER BY amount DESC limit 10");

        return $topTenList;
    }

    /**
     * 我的领取信息
     */
    public function myReceiveInfo($activityId,$userId)
    {
        $where = array('activity_id'=>$activityId,'user_id'=>$userId);
        $myInfo = Db::name('receive')->where($where)->find();
        if ( empty($myInfo) ) {
            $myInfo['recommend_num'] = 0;
            $myInfo['invite_quantity'] = 0;
        }
        $myInfo['type'] = 0;

        return $myInfo;
    }

    /**
     * 根据概率获取用户所得的cam个数
     * @return mixed
     */
    public function getCamRandom()
    {
        $array = array(1=>99,2=>0.4,3=>0.3,4=>0.2,5=>0.1);
        $number = getRandomElement($array);
        if ( $number ==  false ) {
            $number = 0;
        }

        return $number;
    }

    /**
     * 随机获取邀请码
     */
    public  function makeInviteCode(){
        $charId = strtolower(md5(uniqid(rand(), true)));
        $code = substr($charId, 0, 6);
        //查询数据库是否存在邀请码
        $oneInfo = Db::name('receive')->where('invitation_code',$code)->select();
        if( empty($oneInfo) ) {
            return $code;
        }

        $this->makeInviteCode();
    }

    /**
     * 短链接生成
     */
    public function getShoreUrl()
    {
        // 新浪生成短链接接口
        $api = 'http://api.t.sina.com.cn/short_url/shorten.json';
        //AppKey
        $source = '2834085492';
        //长链接
        $url_long = 'http://www.bibowallet.com/home/activity/download';
        //请求url
        $request_url = sprintf($api.'?source=%s&url_long=%s', $source, $url_long);
        //请求结果
        $data = file_get_contents($request_url);

        echo $data;
    }

    /*
     * deviceToken解密
     */
    public function joseDecode($str){
        $private_key  = 'IyIZCUfCOv2NSG75Eo0qoT7xaWDyEhAFHXU3sSNHGvi7X2kJeCoFE4TbYc86MFA2RmZy3XcU';
        $jwt_string =  $str;
        $jws = \JOSE_JWT::decode($jwt_string);
        $resultData = $jws->verify($private_key, 'HS512');
        if ( isset($resultData->claims) ) {
            $result =  $resultData->claims;
        }else {
            $this->error('参数解析错误！');
        }

        return $result;
    }
}
